什么是BFC
BFC(Block Formatting Context,块级格式化上下文),一个BFC区域包含创建该上下文元素的所有子元素,但是不包括创建了新的BFC的子元素的内部元素,BFC是是一块独立的渲染区域,可以将BFC看成是元素的一种属性,拥有了这种属性的元素就会使它的子元素与世隔绝,不会影响到外部其他元素。
例如:
<div class="box1">
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5">
<div class="box6"></div>
<div class="box7"></div>
<div class="box8"></div>
</div>
</div>
假设box1和box5是两个BFC区域,box1这个BFC区域包含了子元素box2、3、4、5,但不包括box6、7、8;box5的区域包含box6、7、8这三个子元素。
总结:
- 每个BFC区域只包括其子元素,不包括其子元素的子元素
- 每一个BFC区域都是独立隔绝的,互不影响
BFC原理(渲染规则|布局规则)
- 内部的Box会在垂直方向,从顶部开始一个接一个的放置
- Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻的Box的margin会发生重叠
- 每个元素的margin box 的左边,与包含块border Box的左边相接触,即使存在浮动也是如此
- BFC在页面上是一个隔离的独立容器,外面的元素不会影响里面的元素,反之亦然
- BFC的区域不会与float Box重叠(可以用这个特性清除浮动)
- 计算BFC的高度时,浮动元素也参与计算(解决父盒子塌陷)
如何使一个元素变为BFC区域
- body根元素
- 设置浮动(不包括none)
- 设置绝对定位,absoulte或者fixed
- 行内块显示模式:display为inline-block
- 设置overflow,即hidden,auto,scroll
- 表格单元,table-cell、table等属性
- 弹性布局flex或inline-flex
BFC作用
- 解决外边距的塌陷问题(垂直塌陷)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.div {
width: 100px;
height: 100px;
background-color: red;
margin: 100px;
}
</style>
</head>
<body>
<div class="div"></div>
<div class="div"></div>
</body>
</html>
但是这两个盒子之间的距离为100px,出现了垂直塌陷(同一个BFC区域的兄弟元素或父子元素会重叠margin),解决方案:给两个盒子都加一个父元素,并且将父元素设置为BFC区域,就可以解决margin塌陷问题。
解决方案:
<style>
.div{
width: 100px;
height: 100px;
background-color: red;
margin: 100px;
}
.div_bfc{
overflow:hidden;
}
</style>
<div class="div_bfc">
<div class="div"></div>
</div>
<div class="div_bfc">
<div class="div"></div>
</div>
- 利用BFC解决包含塌陷
有时候给子元素加margin会带着父元素一起跑
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father {
width: 100px;
height: 100px;
background-color: red;
}
.son {
width: 20px;
height: 20px;
background-color: black;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
在这个例子中,只给son设置margin-top为20px,father会被带着一起走。解决方案:padding/BFC,后者将父盒子变为BFC区域,这样在BFC区域内部的操作不会影响到外部。(父元素的margin算是在父元素外部)
解决方案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father {
width: 100px;
height: 100px;
background-color: red;
overflow: hidden;
}
.son {
width: 20px;
height: 20px;
background-color: black;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
- 清除浮动
浮动会导致父元素高度塌陷,清除浮动的方式:overflow:hidden
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father {
width: 100px;
background-color: red;
}
.son {
width: 20px;
height: 20px;
background-color: black;
/*
float:right
这句话设置之后父容器会塌陷
*/
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
在上例中,不设置父元素的高度,子元素会自动将父元素撑开,但是将子元素设置浮动之后,父元素的高度会塌陷;为了解决这个问题,将父元素设置为BFC区域:overflow:hidden;
原理:独立的块级上下文可以包裹浮动流,全部浮动子元素也不会引起容器高度塌陷,包含块会把浮动元素的高度也计算在内,所以就不用清除浮动来撑起包含块的高度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father {
width: 100px;
background-color: red;
overflow: hidden;
}
.son {
width: 20px;
height: 20px;
background-color: black;
float: right;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
- BFC可以阻止标准流元素被浮动元素覆盖
因为浮动元素会脱离文档流,跑到上一个层面,所以可能会导致浮动元素覆盖基本元素的问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.red {
width: 200px;
height: 200px;
background-color: red;
float: left;
}
.blue {
height: 300px;
background-color: blue;
}
</style>
</head>
<body>
<div class="red"></div>
<div class="blue"></div>
</body>
</html>
在上例中,红色块设置浮动,会覆盖蓝色块,为了让蓝色块不受红色块影响,让蓝色块触发BFC
解决方案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.red {
width: 200px;
height: 200px;
background-color: red;
float: left;
}
.blue {
height: 300px;
background-color: blue;
overflow: hidden;
}
</style>
</head>
<body>
<div class="red"></div>
<div class="blue"></div>
</body>
</html>
让蓝色块触发BFC之后,他就会避开左边的宽度,自适应自己的宽度。